﻿using CIS.DB;
using CIS.Web.Common;
using CIS.Web.Models;
using CIS.Web.Properties;
using System;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace CIS.Web.Controllers
{
	[RoutePrefix("ConferencePayment")]
	public class ConferencePaymentController : BaseDbController
	{
		[Route("Index/{ConferenceId}")]
		public async Task<ActionResult> Index(string conferenceId)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", conferenceId);

			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
						x.ID == conferenceId);

			ViewBag.ConferenceId = conferenceId;
			ViewBag.ConferenceName = conferenceMaster.ConferenceName;
			ViewBag.ControllerName = Resources.ConferencePayment;
			ViewBag.Language = conferenceMaster.IsInternational ? ConstValues.Language.En : ConstValues.Language.Cn;

			var model = new ConferencePaymentModel();
			model.ConferenceId = conferenceId;
			model.IsInternational = conferenceMaster.IsInternational;
			LoginUser.ConferenceFunctionIdList = Utility.GetConferenceFunctionIdList(conferenceId);
			return View(model);
		}

		public async Task<JsonCamelCaseResult> GetData(int? page, int? rows, string sort, string order, ConferencePaymentModel model)
		{
			int take = rows ?? ConstValues.DefaultGridRows;
			int skip = ((page ?? 1) - 1) * take;

			var sql = DbContext.ConferencePaymentMaster.AsNoTracking()
				.Where(x => !string.IsNullOrEmpty(x.Status) && x.ConferenceId == model.ConferenceId)
				    .GroupJoin(DbContext.SysPaymentMaster.AsNoTracking(),
				    con => con.PayId,
				    sys => sys.ID,
				    (con, sys) => new
				    {
					    PaymentName = sys.FirstOrDefault().PaymentName,
					    PaymentNameEn = sys.FirstOrDefault().PaymentNameEn,
					    ID = con.ID,
					    Status = con.Status,
					    Remark = con.Remark,
					    CreateDate = con.CreateDate,
					    CreateIP = con.CreateIP,
					    Creator = con.Creator,
					    Sort = con.Sort,
					    UpdateDate = con.UpdateDate
				    });
			if (!string.IsNullOrWhiteSpace(model.SelPaidType))
			{
				sql = sql.Where(x => x.PaymentName.Contains(model.SelPaidType));
			}
			int total = await sql.CountAsync();

			if (!string.IsNullOrEmpty(sort))
			{
				sql = sql.OrderBy(sort + ConstValues.chrSpace + order).Skip(skip).Take(take);
			}
			else
			{
				sql = sql.OrderBy(x => x.Sort).ThenByDescending(x => x.UpdateDate).ThenBy(x => x.PaymentName).Skip(skip).Take(take);
			}

			var sqlResult = await sql.ToListAsync();

			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
						x.ID == model.ConferenceId);

			var result = sqlResult.Select(x => new
			{
				ID = x.ID,
				PaymentName = conferenceMaster.IsInternational ? x.PaymentNameEn :  x.PaymentName,
				Status = x.Status,
				Sort = x.Sort,
				IsInternational = conferenceMaster.IsInternational,
				Remark = x.Remark,
				Creator = x.Creator,
				CreateIP = x.CreateIP,
				CreateDate = Request.Cookies["_culture"].Value == ConstValues.Language.Cn ?
					x.CreateDate.Value.ToString("yyyy-MM-dd") :
					x.CreateDate.Value.ToString("MM/dd/yyyy")
			});

			return JsonCamelCase(new
			{
				Total = total,
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetEditData(string id)
		{
			var data = await DbContext.ConferencePaymentMaster.AsNoTracking().FirstOrDefaultAsync(x => x.ID == id);
			if (data != null)
			{
				var result = new
				{
					id = data.ID,
					paymentName = data.PayId,
					sort = data.Sort,
					status = data.Status,
					remark = data.Remark
				};
				return JsonCamelCase(Utility.CreateSuccessJsonResult(string.Empty, result),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		public async Task<JsonCamelCaseResult> GetAliData(ConferencePaymentModel model)
		{
			var result = await DbContext.AlipayMaster.AsNoTracking().FirstOrDefaultAsync(x => x.ConferenceId == model.ConferenceId);
			if (result == null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(string.Empty),
						JsonRequestBehavior.AllowGet);
			}

			return JsonCamelCase(Utility.CreateSuccessJsonResult(string.Empty, result),
					JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetEPayData(ConferencePaymentModel model)
		{
			var result = await DbContext.EpayMaster.AsNoTracking().FirstOrDefaultAsync(x => x.ConferenceId == model.ConferenceId);
			if (result == null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(string.Empty),
						JsonRequestBehavior.AllowGet);
			}

			return JsonCamelCase(Utility.CreateSuccessJsonResult(string.Empty, result),
					JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("Create/{ConferenceId}")]
		public async Task<JsonResult> Create(ConferencePaymentModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.ConferencePaymentMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ConferenceId == model.ConferenceId &&
						x.PayId == model.PaidId);

			if (result != null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
						string.Format(Resources.MsgRecordExist, Resources.Name)),
						JsonRequestBehavior.AllowGet);
			}

			var payment = new ConferencePaymentMaster
			{
				ID = Utility.GetTableId(ConstValues.TableName.ConferencePaymentMaster),
				PayId = model.PaidId,
				ConferenceId = model.ConferenceId,
				Status = model.Status,
				Sort = model.Sort.HasValue ? model.Sort.Value : ConstValues.DefaultSort,
				Remark = model.Remark?.Trim(),
				Creator = LoginUser.UserName,
				CreateIP = LoginUser.IP,
				CreateDate = DateTime.Now
			};

			DbContext.ConferencePaymentMaster.Add(payment);
			await DbContext.SaveChangesAsync();

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
					JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("Modify/{ConferenceId}")]
		public async Task<JsonResult> Modify(ConferencePaymentModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var exist = await DbContext.ConferencePaymentMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ID != model.Id &&
						x.ConferenceId == model.ConferenceId &&
						x.PayId == model.PaidId);

			if (exist != null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
						string.Format(Resources.MsgRecordExist, Resources.PaymentType)),
						JsonRequestBehavior.AllowGet);
			}

			var result = await DbContext.ConferencePaymentMaster
					.FirstOrDefaultAsync(x => x.ID == model.Id);

			if (result != null)
			{
				result.PayId = model.PaidId;
				result.Sort = model.Sort.HasValue ? model.Sort.Value : ConstValues.DefaultSort;
				result.Remark = model.Remark?.Trim();
				result.Status = model.Status;

				result.Updater = LoginUser.UserName;
				result.UpdateDate = DateTime.Now;
				result.UpdateIP = LoginUser.IP;

				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("Delete/{ConferenceId}")]
		public async Task<JsonResult> Delete(ConferencePaymentModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var exist = await DbContext.ConferenceAttendenceInfo.AsNoTracking()
					.Where(x => x.PaymentTypeId == model.Id).ToListAsync();

			if (exist.Count > 0)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgUsingCanNotDelete),
						JsonRequestBehavior.AllowGet);
			}

			var pay = await DbContext.ConferencePaymentMaster.FirstOrDefaultAsync(x => x.ID == model.Id);
			var sys = await DbContext.SysPaymentMaster.FirstOrDefaultAsync(x => x.ID == pay.PayId);

			if (sys != null)
			{
				if (sys.PaymentName == ConstValues.PayType.支付宝)
				{
					var alipayMaster = await DbContext.AlipayMaster.FirstOrDefaultAsync(x => x.ConferenceId == pay.ConferenceId);
					if (alipayMaster != null)
					{
						DbContext.AlipayMaster.Remove(alipayMaster);
					}
				}
				if (sys.PaymentName == ConstValues.PayType.易支付)
				{
					var epayMaster = await DbContext.EpayMaster.FirstOrDefaultAsync(x => x.ConferenceId == pay.ConferenceId);
					if (epayMaster != null)
					{
						DbContext.EpayMaster.Remove(epayMaster);
					}
				}

				DbContext.ConferencePaymentMaster.Remove(pay);
				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessDelete),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("CreateAli/{ConferenceId}")]
		public async Task<JsonResult> CreateAli(ConferencePaymentModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.AlipayMaster.FirstOrDefaultAsync(x => x.ConferenceId == model.AliConferenceId);

			if (result != null)
			{
				result.AccountName = model.AccountName;
				result.Partner = model.Partner;
				result.SellerMail = model.SellerEmail;
				result.AlipayKey = model.Alipaykey;
				result.InputCharset = model.InputCharset;
				result.SignType = model.SignType;
				result.Sort = model.AliSort.HasValue ? model.AliSort.Value : ConstValues.DefaultSort;
				result.Remark = model.AliRemark?.Trim();
				result.Status = model.AliStatus;
				result.AppId = model.AppId;
				result.Rsa = model.Rsa;

				result.Updater = LoginUser.UserName;
				result.UpdateDate = DateTime.Now;
				result.UpdateIP = LoginUser.IP;

				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit), JsonRequestBehavior.AllowGet);
			}
			else
			{
				var alipayMaster = new AlipayMaster
				{
					ID = Utility.GetTableId(ConstValues.TableName.AlipayMaster),
					ConferenceId = model.AliConferenceId,
					AccountName = model.AccountName,
					Partner = model.Partner,
					SellerMail = model.SellerEmail,
					AlipayKey = model.Alipaykey,
					InputCharset = model.InputCharset,
					SignType = model.SignType,
					AppId = model.AppId,
					Rsa = model.Rsa,
					Sort = model.AliSort.HasValue ? model.AliSort.Value : ConstValues.DefaultSort,
					Remark = model.AliRemark?.Trim(),
					Status = model.AliStatus,
                                        Creator = LoginUser.UserName,
					CreateIP = LoginUser.IP,
					CreateDate = DateTime.Now
				};

				DbContext.AlipayMaster.Add(alipayMaster);
				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit), JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("CreateE/{ConferenceId}")]
		public async Task<JsonResult> CreateE(ConferencePaymentModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.EpayMaster.FirstOrDefaultAsync(x => x.ConferenceId == model.EConferenceId);

			if (result != null)
			{
				result.TenantId = model.TenantId;
				result.TenantAddress = model.TenantAddress;
				result.TenantMail = model.TenantMail;
				result.TenantName = model.TenantName;
				result.TenantPostcode = model.TenantPost;
				result.TenantPhone = model.TenantTel;
				result.Country = model.Country;
				result.City = model.State;
				result.Area = model.City;
				result.Key = model.EPayKey;
				result.Sort = model.ESort.HasValue ? model.ESort.Value : ConstValues.DefaultSort;
				result.Remark = model.ERemark?.Trim();
				result.Status = model.EStatus;

				result.Updater = LoginUser.UserName;
				result.UpdateDate = DateTime.Now;
				result.UpdateIP = LoginUser.IP;

				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit), JsonRequestBehavior.AllowGet);
			}
			else
			{
				var epayMaster = new EpayMaster
				{
					ID = Utility.GetTableId(ConstValues.TableName.EpayMaster),
					ConferenceId = model.EConferenceId,
					TenantId = model.TenantId,
					TenantAddress = model.TenantAddress,
					TenantMail = model.TenantMail,
					TenantName = model.TenantName,
					TenantPostcode = model.TenantPost,
					TenantPhone = model.TenantTel,
					Country = model.Country,
					City = model.State,
					Area = model.City,
					Key = model.EPayKey,
					Sort = model.ESort.HasValue ? model.ESort.Value : ConstValues.DefaultSort,
					Remark = model.ERemark?.Trim(),
					Status = model.EStatus,
					Creator = LoginUser.UserName,
					CreateIP = LoginUser.IP,
					CreateDate = DateTime.Now
				};

				DbContext.EpayMaster.Add(epayMaster);
				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit), JsonRequestBehavior.AllowGet);
			}
		}

		public async Task<JsonResult> GetPayType(string conferenceId)
		{
			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ID == conferenceId);

			if (conferenceMaster.IsInternational)
			{
				var result = await DbContext.SysPaymentMaster.AsNoTracking().Where(x=> x.Status == ConstValues.Status.正常)
				.OrderBy(x => x.PaymentName)
				.Select(x => new
				{
					Id = x.ID,
					Name = x.PaymentNameEn
				})
				.ToListAsync();

				return JsonCamelCase(result, JsonRequestBehavior.AllowGet);
			}
			else
			{
				var result = await DbContext.SysPaymentMaster.AsNoTracking().Where(x => x.Status == ConstValues.Status.正常)
						.OrderBy(x => x.PaymentName)
						.Select(x => new
						{
							Id = x.ID,
							Name = x.PaymentName
						})
						.ToListAsync();

				return JsonCamelCase(result, JsonRequestBehavior.AllowGet);
			}
		}
	}
}